import { commonReduxGenerator } from 'utils/reduxGenerator/index'
import store from 'store'
import _ from 'lodash'
import axios from 'axios'

import { getHouse } from 'model/house'

import { wait } from 'utils/wait'

import { calcHouse } from 'config/money'
import { url, api } from 'config/api'

// 补充用户信息,从url得到
const input_user_info = 'input_user_info'

const get_preselect_loading = 'get_preselect_loading'
const get_preselect_loaded = 'get_preselect_loaded'
const get_preselect_success = 'get_preselect_success'
const get_preselect_error = 'get_preselect_error'

const add_preselect_loading = 'add_preselect_loading'
const add_preselect_loaded = 'add_preselect_loaded'
const add_preselect_success = 'add_preselect_success'
const add_preselect_error = 'add_preselect_error'

const remove_preselect_loading = 'remove_preselect_loading'
const remove_preselect_loaded = 'remove_preselect_loaded'
const remove_preselect_success = 'remove_preselect_success'
const remove_preselect_error = 'remove_preselect_error'

const get_lock_house_loading = 'get_lock_house_loading'
const get_lock_house_loaded = 'get_lock_house_loaded'
const get_lock_house_success = 'get_lock_house_success'
const get_lock_house_error = 'get_lock_house_error'

const lock_house_loading = 'lock_house_loading'
const lock_house_loaded = 'lock_house_loaded'
const lock_house_success = 'lock_house_success'
const lock_house_error = 'lock_house_error'

// 登录
const login_loading = 'login_loading'
const login_loaded = 'login_loaded'
const login_fail = 'login_fail'
const login_success = 'login_success'

// 更新支付时间
const update_pay_index = 'update_pay_index'

// 支付时间有效期 单位 秒
const payLimit = 0

export const {
  reducer,

  success,
  error,
  reset,
  loading,
  loaded
} = commonReduxGenerator({
  type: 'user',

  state: {
    // 姓名
    name: '',
    // 手机号
    phone: '',
    // 身份证号码
    idcard: '',

    // 备选最大值
    preSelectLimit: 5,
    // 锁房最大值
    lockHouseLimit: 1,
    // 支付时间
    payLimit,
    payIndex: payLimit,

    // 我的备选房源
    preSelectHouse: [],

    getPreSelectLoading: false,
    getPreSelectRefreshing: 0,
    getPreSelectInit: false,
    getPreSelectMsg: '',

    addPreSelectLoading: false,
    addPreSelectMsg: '',
    removePreSelectLoading: false,
    removePreSelectMsg: '',

    /**
     * [lockHouse 锁定房源]
     * @type {Object Array}
     *
     * @param  {String}       houseId            [房源id]
     * @param  {String}       houseOrderId       [房源订单id]
     *
     * @param  {String}       backup1             [支付方式]
     *                                              1: pos收款 (二维码)
     *                                              2: 线下收款
     *                                              3: 线上收款 (在线支付)
     *
     * @param  {String}       payStatus           [订单状态]
     *                                              0: 锁房成功(待支付)
     *                                              1: 认购成功
     *                                              2: 支付失败
     *                                              9: 支付超时
     *
     * @param  {String}       protocolLookStatus [协议查看状态]
     *                                             0: 未看
     *                                             1: 已看
     *
     * @param  {Number|Null}  hTotalPrice        [总房价]
     * @param  {Number|Null}  stationaryMoney    [定金]
     * @param  {String}       hosUnitArea        [建筑面积]
     * @param  {Number|Null}  hosUnitPrice       [建筑面积单价]
     * @param  {String}       setInArea          [套内面积]
     * @param  {Number|Null}  setInPrice         [套内面积单价]
     *
     * @param  {String}       manageEndDate      [认购截止时间 2019-09-09 16:45:00.0]
     * @param  {Number|Null}  tradeTime          [下单时间/开始支付时间 具体时间点 时间戳 1539076027000]
     * @param  {Number|Null}  paymentDate        [支付间隔时间 单位 分钟]
     *
     * @param  {String}       buildNumName       [完整房号 楼栋 + 单元 + 楼层 + 房号]
     * @param  {String}       floor              [楼层]
     * @param  {String}       housePreiodName    [期数]
     * @param  {String}       householdNo        [房号]
     *
     * @param  {Number|Null}  preSelectNum       [备选人数]
     *
     * @param  {String}       realName           [姓名]
     * @param  {String}       idCardNo           [身份证号码]
     * @param  {String}       phone              [手机号码]
     * @param  {Number|Null}  bankCardNo         [银行卡号]
     */
    lockHouse: [],

    getLockHouseLoading: false,
    getLockHouseRefreshing: 0,
    getLockHouseInit: false,
    getLockHouseMsg: '',

    lockLoading: false,
    lockMsg: '',

    // 登录状态签名
    token: '',
    // 权限
    auth: ['unlogin'],

    // 登录相关
    login_loading: false,
    login_msg: ''
  },

  action: [{
    action: login_loading,
    result: (state, payload, isRefresh) => {
      return {
        ...state,

        login_msg: '',
        login_loading: true
      }
    }
  }, {
    action: login_loaded,
    result: (state, payload, isRefresh) => {
      return {
        ...state,

        login_msg: '',
        login_loading: false
      }
    }
  }, {
    action: login_fail,
    result: (state, payload, isRefresh) => {
      return {
        ...state,

        login_msg: payload,
      }
    }
  }, {
    action: login_success,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        ...payload,

        auth: ['login']
      }
    }
  }, {
    action: input_user_info,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        ...payload,
        auth: ['login']
      }
    }
  }, {
    action: get_preselect_loading,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        getPreSelectMsg: '',
        getPreSelectLoading: true,
        getPreSelectRefreshing: isRefresh ? 1 : state.getPreSelectRefreshing
      }
    }
  }, {
    action: get_preselect_loaded,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        getPreSelectLoading: false
      }
    }
  }, {
    action: get_preselect_success,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        preSelectHouse: payload,
        getPreSelectInit: true,
        getPreSelectRefreshing: isRefresh ? 2 : state.getPreSelectRefreshing
      }
    }
  }, {
    action: get_preselect_error,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        getPreSelectMsg: payload,
        getPreSelectRefreshing: isRefresh ? -1 : state.getPreSelectRefreshing
      }
    }
  }, {
    action: add_preselect_loading,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        addPreSelectLoading: true
      }
    }
  }, {
    action: add_preselect_loaded,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        addPreSelectLoading: false
      }
    }
  }, {
    action: add_preselect_success,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        // preSelectHouse: [payload].concat(state.preSelectHouse)
        preSelectHouse: payload
      }
    }
  }, {
    action: add_preselect_error,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        addPreSelectMsg: payload
      }
    }
  }, {
    action: remove_preselect_loading,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        removePreSelectLoading: true
      }
    }
  }, {
    action: remove_preselect_loaded,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        removePreSelectLoading: false
      }
    }
  }, {
    action: remove_preselect_success,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        preSelectHouse: state.preSelectHouse.filter(v => v.houseId !== payload.houseId)
      }
    }
  }, {
    action: remove_preselect_error,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        removePreSelectMsg: payload
      }
    }
  }, {
    action: get_lock_house_loading,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        getLockHouseMsg: '',
        getLockHouseLoading: true,
        getLockHouseRefreshing: isRefresh ? 1 : state.getLockHouseRefreshing
      }
    }
  }, {
    action: get_lock_house_loaded,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        getLockHouseLoading: false
      }
    }
  }, {
    action: get_lock_house_success,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        lockHouse: payload,
        getLockHouseInit: true,
        getLockHouseRefreshing: isRefresh ? 2 : state.getLockHouseRefreshing
      }
    }
  }, {
    action: get_lock_house_error,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        getLockHouseMsg: payload,
        getLockHouseRefreshing: isRefresh ? -1 : state.getLockHouseRefreshing
      }
    }
  }, {
    action: lock_house_loading,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        lockLoading: true
      }
    }
  }, {
    action: lock_house_loaded,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        lockLoading: false
      }
    }
  }, {
    action: lock_house_success,
    result: (state, payload, isRefresh) => {
      const {
        houseId,
        data
      } = payload

      return {
        ...state,
        lockHouse: data,
        preSelectHouse: state.preSelectHouse.filter(v => v.houseId !== houseId)
      }
    }
  }, {
    action: lock_house_error,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        lockMsg: payload
      }
    }
  }, {
    action: update_pay_index,
    result: (state, payload, isRefresh) => {
      return {
        ...state,
        payIndex: payload
      }
    }
  }]
})

export function inputUserInfo (payload) {
  const user = store.get('user') || {}

  // 缓存起
  store.set('user', {
    // ...user,
    ...payload
  })

  return {
    payload,
    type: input_user_info
  }
}

export function getPreselect (params = {}, isRefresh, ignoreCache) {
  return async (dispatch, getState) => {

    const {
      user: {
        getPreSelectLoading,
        getPreSelectInit,
        preSelectHouse: _preSelectHouse,
      }
    } = getState()

    if (getPreSelectLoading) {
      return ['重复请求']
    }

    if (getPreSelectInit && !ignoreCache && !isRefresh) {
      return [_preSelectHouse]
    }

    dispatch({ isRefresh, type: get_preselect_loading })

    const [err, res] = await axios.post(url.server + api.getPreSelectHouse, params)

    dispatch({ isRefresh, type: get_preselect_loaded })

    if (err) {
      dispatch({ isRefresh, payload: err, type: get_preselect_error })

      return [err]
    }

    let preSelectHouse = []

    if (res.data && _.isArray(res.data.houseOrders)) {
      preSelectHouse = res.data.houseOrders
    }

    dispatch({
      isRefresh,
      payload: preSelectHouse.map(v => ({
        ...v,
        ...calcHouse(v)
      })),
      type: get_preselect_success
    })

    return [null, res.data]
  }
}

export function getLockHouse (params = {}, isRefresh, ignoreCache) {
  return async (dispatch, getState) => {
    const {
      user: {
        getLockHouseLoading,
        getLockHouseInit,
        lockHouse: _lockHouse
      }
    } = getState()

    if (getLockHouseLoading) {
      return ['重复请求']
    }

    if (getLockHouseInit && !ignoreCache && !isRefresh) {
      return [_lockHouse]
    }

    dispatch({ isRefresh, type: get_lock_house_loading })

    const [err, res] = await axios.post(url.server + api.getLockHouse, params)

    dispatch({ isRefresh, type: get_lock_house_loaded })

    if (err) {
      dispatch({ isRefresh, payload: err, type: get_lock_house_error })

      return [err]
    }

    let lockHouse = []

    if (res.data && _.isArray(res.data.houseOrders)) {
      lockHouse = res.data.houseOrders
    }

    dispatch({
      isRefresh,
      payload: lockHouse.map(v => ({
        ...v,
        ...calcHouse(v)
      })),
      type: get_lock_house_success
    })

    return [null, res.data]
  }
}

// 添加备选
export function addPreSelect (params = {}) {
  return async (dispatch, getState) => {
    const {
      user: {
        addPreSelectLoading,
        preSelectLimit,
        preSelectHouse
      }
    } = getState()

    if (addPreSelectLoading) {
      return ['重复请求']
    }

    if (preSelectLimit !== 0 && preSelectHouse.length >= preSelectLimit) {
      // dispatch({
      //   type: add_preselect_success,
      //   payload: `最多备选${ preSelectLimit }套房源哦`
      // })

      return [`最多备选${ preSelectLimit }套房源哦`]
    }

    dispatch({ type: add_preselect_loading })

    const [err, res] = await axios.post(url.server + api.addPreSelect, params)

    dispatch({ type: add_preselect_loaded })

    if (err) {
      dispatch({ type: add_preselect_error, payload: err })

      return [err]
    }

    const {
      data,
      data: {
        houseOrders = []
      }
    } = res

    dispatch({
      type: add_preselect_success,
      payload: houseOrders.map(v => ({
        ...v,
        ...calcHouse(v)
      }))
    })


    dispatch(getHouse({}, true))

    return [null, data]
  }
}

// 移除备选
export function removePreSelect (params = {}) {
  return async (dispatch, getState) => {
    const {
      user: {
        removePreSelectLoading
      }
    } = getState()

    if (removePreSelectLoading) {
      return ['重复请求']
    }

    dispatch({ type: remove_preselect_loading })

    const [err, res] = await axios.post(url.server + api.removePreSelect, params)

    dispatch({ type: remove_preselect_loaded })

    if (err) {
      dispatch({ type: remove_preselect_error, payload: err })

      return [err]
    }

    dispatch({
      type: remove_preselect_success,
      payload: {
        houseId: params.houseId
      }
    })

    dispatch(getHouse({}, true))

    return [null, res]
  }
}

export function lockHouse (params = {}) {
  return async (dispatch, getState) => {
    const {
      user: {
        lockLoading,
        lockHouseLimit,
        lockHouse
      },
      house: {
        type
      }
    } = getState()

    if (lockLoading) {
      return ['重复请求']
    }

    if (type !== 1) {
      return ['现在还不能锁房哦']
    }

    if (lockHouseLimit !== 0 && lockHouse.length >= lockHouseLimit) {
      // dispatch({
      //   type: lock_house_error,
      //   payload: `1位用户只能锁定${ lockHouseLimit }套房哦`
      // })

      return [`1位用户只能锁定${ lockHouseLimit }套房哦`]
    }

    dispatch({ type: lock_house_loading })

    const [err, res] = await axios.post(url.server + api.lockHouse, params)

    if (err) {
      dispatch({ type: lock_house_loaded })
      dispatch({ type: lock_house_error, payload: err })

      return [err]
    }

    const {
      data: {
        code,
        msg
      }
    } = res

    if (code !== 0) {
      dispatch({ type: lock_house_loaded })
      dispatch({
        type: lock_house_error,
        payload: msg || '锁房失败'
      })

      return [msg || '锁房失败']
    }

    const [_err, _res] = await loopQueryLockStatus(params)

    dispatch({ type: lock_house_loaded })

    if (_err) {
      dispatch({ type: lock_house_error, payload: _err })

      return [_err]
    }

    dispatch({
      type: lock_house_success,
      payload: {
        houseId: params.houseId,
        data: _res,
      }
    })

    dispatch(getHouse({}, true))

    return [null, _res]
  }
}

export async function loopQueryLockStatus (params = {}, timeout = 31) {
  let timeout_index = 0

  /* eslint no-constant-condition: 0 */
  while (
    timeout_index < timeout || timeout <= 0
  ) {
    if (timeout_index + 2 > timeout && timeout !== 0) {
      return ['锁房超时', 3]
    }

    if (timeout > 0) {
      timeout_index += 1
    }

    const [err, res] = await axios.post(url.server + api.loopQueryLockStatus, params)

    if (err) {
      return [err]
    }

    let {
      data: {
        state,
        msg,
        houseOrders
      }
    } = res

    if (_.isPlainObject(houseOrders)) {
      houseOrders = [houseOrders]
    }

    if (state === 2) {
      return [msg || '来迟一步，房源已被别人锁定', state]
    }

    if (state === 0) {
      return [
        null,
        houseOrders.map(v => ({
          ...v,
          ...calcHouse(v)
        }))
      ]
    }

    await wait(1)
  }
}

// 登录
const loginLoading = payload => ({ payload, type: login_loading })
const loginLoaded = payload => ({ payload, type: login_loaded })
const loginFail = payload => ({ payload, type: login_fail })
const loginSuccess = payload => ({ payload, type: login_success })

export function login (params = {}) {
  return async (dispatch, getState) => {
    const {
      user: {
        login_loading,
        token
      }
    } = getState()

    if (login_loading) {
      return ['重复请求']
    }

    dispatch(loginLoading())

    const [err, res] = await axios.post(url.server + api.login, params)

    dispatch(loginLoaded())

    if (err) {
      return [err]
    }

    const {
      data: {
        Authorization
      }
    } = res

    store.set('token', Authorization)

    return [null, res]

  }
}

// 更新支付时间
export function updatePayIndex (payload) {
  return { payload, type: update_pay_index }
}
